package hos.okhttp.http;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.concurrent.ConcurrentLinkedQueue;

import hos.http.HttpUtils;
import hos.http.Progress;
import hos.http.ProgressListener;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * <p>Title: ProgressResponseBody </p>
 * <p>Description: 上传监听 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023-02-24 19:17
 */
public class ProgressRequestBody extends RequestBody {
    private final ConcurrentLinkedQueue<ProgressListener> progressListeners;

    private final RequestBody body;
    private final Progress progress;

    private long contentLength;

    public ProgressRequestBody(ConcurrentLinkedQueue<ProgressListener> progressListeners, RequestBody body) {
        this.progressListeners = progressListeners;
        this.body = body;
        progress = new Progress();
    }

    private long getContentLength() throws IOException {
        if (contentLength == 0L) {
            contentLength = body.contentLength();
        }
        return contentLength;
    }

    @Override
    public long contentLength() throws IOException {
        return getContentLength();
    }

    @Nullable
    @Override
    public MediaType contentType() {
        return body.contentType();
    }


    @Override
    public void writeTo(@NotNull BufferedSink sink) throws IOException {
        if (sink instanceof Buffer ||
                sink.toString().contains("com.android.tools.profiler.support.network.HttpTracker.OutputStreamTracker")) {
            body.writeTo(sink);
        } else {
            BufferedSink bufferedSink = Okio.buffer(new ProgressSink(sink));
            body.writeTo(bufferedSink);
            bufferedSink.close();
        }
    }

    class ProgressSink extends ForwardingSink {
        Long writeByteCount = 0L;

        public ProgressSink(@NotNull Sink delegate) {
            super(delegate);
        }

        @Override
        public void write(@NotNull Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            HttpUtils.progressRequestBody(progressListeners, progress, getContentLength(), writeByteCount, byteCount);
//            writeByteCount += byteCount;
//            if (progressListeners != null) {
//                long currentElapsedTime = SystemClock.elapsedRealtime();
//                for (ProgressListener listener : progressListeners) {
//                    listener.intervalByteCount += byteCount;
//                    long currentInterval = currentElapsedTime - listener.elapsedTime;
//                    if (currentInterval >= listener.interval || writeByteCount == contentLength) {
//                        progress.currentByteCount = writeByteCount;
//                        progress.totalByteCount = contentLength;
//                        progress.intervalByteCount = listener.intervalByteCount;
//                        progress.intervalTime = currentInterval;
//                        listener.onProgress(progress);
//                        listener.elapsedTime = currentElapsedTime;
//                        listener.intervalByteCount = 0L;
//                    }
//                }
//            }
        }
    }
}
